home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / termScroll.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  14KB  |  633 lines

  1. /*
  2. **    $Id: termScroll.c,v 1.4 92/05/09 15:54:33 olsen Sta Locker: olsen $
  3. **    $Revision: 1.4 $
  4. **    $Date: 92/05/09 15:54:33 $
  5. **
  6. **    Support routines for optimized screen scrolling.
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* ScrollLineRectFill():
  15.      *
  16.      *    Fill a rectangular portion of the window raster with the help
  17.      *    of the scrolling information.
  18.      */
  19.  
  20. VOID __regargs
  21. ScrollLineRectFill(struct RastPort *RPort,WORD MinX,WORD MinY,WORD MaxX,WORD MaxY)
  22. {
  23.     if(RPort -> BitMap -> Depth == 1)
  24.         RectFill(RPort,MinX,MinY,MaxX,MaxY);
  25.     else
  26.     {
  27.         if(MinX < MaxX)
  28.         {
  29.             /* Is there anything on the screen at all? */
  30.  
  31.             if(ScrollLineFirst <= ScrollLineLast)
  32.             {
  33.                 WORD ScrollLineMask = 0,ScrollLineLeft = 32767,ScrollLineRight = 0,Temp,i;
  34.  
  35.                     /* Determine screen colour mask. */
  36.  
  37.                 for(i = MinY >> 3 ; i <= MaxY >> 3 ; i++)
  38.                 {
  39.                     if(ScrollLines[i] . Shift)
  40.                     {
  41.                         if((Temp = ScrollLines[i] . Left << ScrollLines[i] . Shift) < ScrollLineLeft)
  42.                             ScrollLineLeft = Temp;
  43.  
  44.                         if((Temp = (ScrollLines[i] . Right << ScrollLines[i] . Shift) - 1) > ScrollLineRight)
  45.                             ScrollLineRight = Temp;
  46.  
  47.                         ScrollLineMask |= ScrollLines[i] . ColourMask;
  48.                     }
  49.                 }
  50.  
  51.                     /* Wrap the bits. */
  52.  
  53.                 ScrollLineMask &= (1 << Screen -> RastPort . BitMap -> Depth) - 1;
  54.  
  55.                     /* Did we get a sensible colour? */
  56.  
  57.                 if(ScrollLineMask && ScrollLineLeft <= ScrollLineRight)
  58.                 {
  59.                         /* Determine new left margin. */
  60.  
  61.                     if(ScrollLineLeft > MinX)
  62.                         MinX = ScrollLineLeft;
  63.  
  64.                         /* Determine new right margin. */
  65.  
  66.                     if(ScrollLineRight < MaxX)
  67.                         MaxX = ScrollLineRight;
  68.  
  69.                         /* Determine new top line margin. */
  70.  
  71.                     if((Temp = ScrollLineFirst << 3) > MinY)
  72.                         MinY = Temp;
  73.  
  74.                         /* Determine new bottom line margin. */
  75.  
  76.                     if((Temp = ((ScrollLineLast + 1) << 3) - 1) < MaxY)
  77.                         MaxY = Temp;
  78.  
  79.                         /* Set the colour mask. */
  80.  
  81.                     if(!(Config . DisableBlinking & TERMINAL_FASTER))
  82.                         SetWrMsk(RPort,ScrollLineMask);
  83.  
  84.                         /* And clear the raster. */
  85.  
  86.                     if(MinX < MaxX && MinY < MaxY)
  87.                     {
  88.                         if(MaxX == ScrollLineRight)
  89.                             RectFill(RPort,MinX,MinY,MaxX + 4,MaxY);
  90.                         else
  91.                             RectFill(RPort,MinX,MinY,MaxX,MaxY);
  92.                     }
  93.                 }
  94.             }
  95.         }
  96.     }
  97. }
  98.  
  99.     /* ScrollLineRaster():
  100.      *
  101.      *    Scroll the window raster with the help
  102.      *    of the scrolling information.
  103.      */
  104.  
  105. VOID __regargs
  106. ScrollLineRaster(struct RastPort *RPort,WORD DeltaX,WORD DeltaY,WORD MinX,WORD MinY,WORD MaxX,WORD MaxY)
  107. {
  108.     if(RPort -> BitMap -> Depth == 1)
  109.         ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  110.     else
  111.     {
  112.         if(MinX < MaxX)
  113.         {
  114.             WORD ScrollLineMask;
  115.  
  116.                 /* Are we to scroll a line in horizontal direction? If so, use the
  117.                  * colour mask of the current line.
  118.                  */
  119.  
  120.             if(DeltaX)
  121.             {
  122.                 if(ScrollLineMask = ScrollLines[CursorY] . ColourMask & ((1 << Screen -> RastPort . BitMap -> Depth) - 1))
  123.                 {
  124.                         /* Set the colour mask. */
  125.  
  126.                     if(!(Config . DisableBlinking & TERMINAL_FASTER))
  127.                         SetWrMsk(RPort,ScrollLineMask);
  128.  
  129.                         /* And scroll the raster. */
  130.  
  131.                     ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  132.                 }
  133.             }
  134.             else
  135.             {
  136.                     /* Any data on screen worth scrolling? */
  137.  
  138.                 if(ScrollLineFirst <= ScrollLineLast)
  139.                 {
  140.                     WORD Temp,First,Last,SaveMinY = MinY >> 3,SaveMaxY = MaxY >> 3,ScrollLineLeft = 32767,ScrollLineRight = 0,i;
  141.  
  142.                         /* Reset colourmask. */
  143.  
  144.                     ScrollLineMask = 0;
  145.  
  146.                         /* Build both the colour mask and the margins. */
  147.  
  148.                     for(i = MinY >> 3 ; i <= MaxY >> 3 ; i++)
  149.                     {
  150.                         if(ScrollLines[i] . Shift)
  151.                         {
  152.                             if((Temp = ScrollLines[i] . Left << ScrollLines[i] . Shift) < ScrollLineLeft)
  153.                                 ScrollLineLeft = Temp;
  154.  
  155.                             if((Temp = (ScrollLines[i] . Right << ScrollLines[i] . Shift) - 1) > ScrollLineRight)
  156.                                 ScrollLineRight = Temp;
  157.  
  158.                             ScrollLineMask |= ScrollLines[i] . ColourMask;
  159.                         }
  160.                     }
  161.  
  162.                         /* Wrap the bits. */
  163.  
  164.                     ScrollLineMask &= (1 << Screen -> RastPort . BitMap -> Depth) - 1;
  165.  
  166.                         /* Sensible results? */
  167.  
  168.                     if(ScrollLineMask && ScrollLineLeft <= ScrollLineRight)
  169.                     {
  170.                             /* Determine new left margin. */
  171.  
  172.                         if(ScrollLineLeft > MinX)
  173.                             MinX = ScrollLineLeft;
  174.  
  175.                             /* Determine new right margin. */
  176.  
  177.                         if(ScrollLineRight < MaxX)
  178.                             MaxX = ScrollLineRight;
  179.  
  180.                             /* Scroll down or up? */
  181.  
  182.                         if(DeltaY < 0)
  183.                         {
  184.                                 /* So we are to scroll down, find the first
  185.                                  * blank line if any.
  186.                                  */
  187.  
  188.                             if((Temp = ScrollLineFirst << 3) > MinY)
  189.                                 MinY = Temp;
  190.  
  191.                                 /* Find the last blank lines if any. */
  192.  
  193.                             if((Temp = ((ScrollLineLast + 1) << 3) - DeltaY - 1) < MaxY)
  194.                                 MaxY = Temp;
  195.  
  196.                                 /* Determine margins and the like... */
  197.  
  198.                             Last    = (MaxY + 1) >> 3;
  199.                             First    = Last - ((MaxY - MinY + 8 + DeltaY) >> 3);
  200.                             Temp    = (-DeltaY) >> 3;
  201.  
  202.                                 /* Move the scroll line info up. */
  203.  
  204.                             for(i = Last - 1 ; i >= First ; i--)
  205.                                 ScrollLines[i] = ScrollLines[i - Temp];
  206.  
  207.                                 /* Clear the remaining lines. */
  208.  
  209.                             for(i = First - Temp ; i < First ; i++)
  210.                             {
  211.                                 ScrollLines[i] . Left        = 255;
  212.                                 ScrollLines[i] . Right        = 0;
  213.                                 ScrollLines[i] . ColourMask    = 0;
  214.                                 ScrollLines[i] . Shift        = 0;
  215.                             }
  216.  
  217.                                 /* Is the first line we were working
  218.                                  * on the first line of the whole display?
  219.                                  * If so, update the line marker.
  220.                                  */
  221.  
  222.                             if(!SaveMinY)
  223.                                 ScrollLineFirst += Temp;
  224.  
  225.                                 /* Now take a look at the last line.
  226.                                  * If the last line we were working
  227.                                  * on is in fact the last line of the
  228.                                  * display, update the line marker.
  229.                                  */
  230.  
  231.                             if(SaveMaxY == LastLine)
  232.                             {
  233.                                 ScrollLineLast += Temp;
  234.  
  235.                                 if(ScrollLineLast > LastLine)
  236.                                     ScrollLineLast = LastLine;
  237.                             }
  238.                         }
  239.                         else
  240.                         {
  241.                                 /* So we are to scroll up, find the last
  242.                                  * blank line if any.
  243.                                  */
  244.  
  245.                             if((Temp = ((ScrollLineLast + 1) << 3) - 1) < MaxY)
  246.                                 MaxY = Temp;
  247.  
  248.                                 /* Find the first blank lines if any. */
  249.  
  250.                             if((Temp = (ScrollLineFirst << 3) - DeltaY) > MinY)
  251.                                 MinY = Temp;
  252.  
  253.                                 /* Determine margins and the like... */
  254.  
  255.                             First    = MinY >> 3;
  256.                             Last    = ((MaxY - MinY + 8 - DeltaY) >> 3);
  257.                             Temp    = DeltaY >> 3;
  258.  
  259.                                 /* Move the scroll line info down. */
  260.  
  261.                             for(i = First ; i < First + Last ; i++)
  262.                                 ScrollLines[i] = ScrollLines[i + Temp];
  263.  
  264.                                 /* Clear the remaining lines. */
  265.  
  266.                             for(i = First + Last ; i < First + Last + Temp ; i++)
  267.                             {
  268.                                 ScrollLines[i] . Left        = 255;
  269.                                 ScrollLines[i] . Right        = 0;
  270.                                 ScrollLines[i] . ColourMask    = 0;
  271.                                 ScrollLines[i] . Shift        = 0;
  272.                             }
  273.  
  274.                                 /* Decrease number of last line. */
  275.  
  276.                             if(SaveMaxY == LastLine)
  277.                             {
  278.                                 if(ScrollLineLast > Temp)
  279.                                     ScrollLineLast -= Temp;
  280.                                 else
  281.                                     ScrollLineLast = 0;
  282.                             }
  283.  
  284.                                 /* Decrease number of first line. */
  285.  
  286.                             if(!SaveMinY)
  287.                             {
  288.                                 if(ScrollLineFirst > Temp)
  289.                                     ScrollLineFirst -= Temp;
  290.                                 else
  291.                                     ScrollLineFirst = 0;
  292.                             }
  293.                         }
  294.  
  295.                             /* Adapt possible changes in the lines for first and last line. */
  296.  
  297.                         while(ScrollLineFirst < RasterHeight)
  298.                         {
  299.                             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  300.                                 ScrollLineFirst++;
  301.                             else
  302.                                 break;
  303.                         }
  304.  
  305.                         while(ScrollLineLast > 0)
  306.                         {
  307.                             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  308.                                 ScrollLineLast--;
  309.                             else
  310.                                 break;
  311.                         }
  312.  
  313.                             /* Set the colour mask. */
  314.  
  315.                         if(!(Config . DisableBlinking & TERMINAL_FASTER))
  316.                             SetWrMsk(RPort,ScrollLineMask);
  317.  
  318.                             /* And scroll the raster. */
  319.  
  320.                         if(MinX < MaxX && MinY < MaxY)
  321.                         {
  322.                             if(MaxX == ScrollLineRight)
  323.                                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX + 4,MaxY);
  324.                             else
  325.                                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  326.                         }
  327.                     }
  328.                 }
  329.             }
  330.         }
  331.     }
  332. }
  333.  
  334.     /* ScrollLineEraseScreen(BYTE Mode):
  335.      *
  336.      *    Erase a part of the screen.
  337.      */
  338.  
  339. VOID __regargs
  340. ScrollLineEraseScreen(BYTE Mode)
  341. {
  342.     if(RPort -> BitMap -> Depth > 1)
  343.     {
  344.         WORD i;
  345.  
  346.         switch(Mode)
  347.         {
  348.                 /* Erase from first line to current cursor line (inclusive). */
  349.  
  350.             case 1:    ScrollLineFirst = CursorY;
  351.  
  352.                     /* Reset the lines. */
  353.  
  354.                 for(i = 0 ; i < CursorY ; i++)
  355.                 {
  356.                     ScrollLines[i] . Left        = 255;
  357.                     ScrollLines[i] . Right        = 0;
  358.                     ScrollLines[i] . ColourMask    = 0;
  359.                     ScrollLines[i] . Shift        = 0;
  360.                 }
  361.  
  362.                 ScrollLines[CursorY] . Left = CursorX + 1;
  363.  
  364.                 if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  365.                 {
  366.                     ScrollLines[CursorY] . Left    = 255;
  367.                     ScrollLines[CursorY] . Right    = 0;
  368.                 }
  369.  
  370.                 break;
  371.  
  372.                 /* Erase entire screen. */
  373.  
  374.             case 2:    for(i = 0 ; i < RasterHeight ; i++)
  375.                 {
  376.                     ScrollLines[i] . Left        = 255;
  377.                     ScrollLines[i] . Right        = 0;
  378.                     ScrollLines[i] . ColourMask    = 0;
  379.                     ScrollLines[i] . Shift        = 0;
  380.                 }
  381.  
  382.                 ScrollLineFirst    = 255;
  383.                 ScrollLineLast    = 0;
  384.  
  385.                 break;
  386.  
  387.                 /* Erase from current cursor position to end of screen. */
  388.  
  389.             default:for(i = CursorY + 1 ; i < RasterHeight ; i++)
  390.                 {
  391.                     ScrollLines[i] . Left        = 255;
  392.                     ScrollLines[i] . Right        = 0;
  393.                     ScrollLines[i] . ColourMask    = 0;
  394.                     ScrollLines[i] . Shift        = 0;
  395.                 }
  396.  
  397.                 if(CursorX)
  398.                 {
  399.                     ScrollLines[CursorY] . Right = CursorX;
  400.  
  401.                     if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  402.                     {
  403.                         ScrollLines[CursorY] . Left    = 255;
  404.                         ScrollLines[CursorY] . Right    = 0;
  405.                     }
  406.                 }
  407.                 else
  408.                 {
  409.                     ScrollLines[CursorY] . Left    = 255;
  410.                     ScrollLines[CursorY] . Right    = 0;
  411.                 }
  412.  
  413.                     /* Cleared the entire screen? */
  414.  
  415.                 if(CursorY)
  416.                     ScrollLineLast = CursorY;
  417.                 else
  418.                 {
  419.                     ScrollLineFirst    = 255;
  420.                     ScrollLineLast    = 0;
  421.                 }
  422.  
  423.                 break;
  424.         }
  425.  
  426.             /* Adapt possible changes in the lines for first and last line. */
  427.  
  428.         while(ScrollLineFirst < RasterHeight)
  429.         {
  430.             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  431.                 ScrollLineFirst++;
  432.             else
  433.                 break;
  434.         }
  435.  
  436.         while(ScrollLineLast > 0)
  437.         {
  438.             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  439.                 ScrollLineLast--;
  440.             else
  441.                 break;
  442.         }
  443.     }
  444. }
  445.  
  446.     /* ScrollLineEraseLine(BYTE Mode):
  447.      *
  448.      *    Erase parts of the current cursor line.
  449.      */
  450.  
  451. VOID __regargs
  452. ScrollLineEraseLine(BYTE Mode)
  453. {
  454.     if(RPort -> BitMap -> Depth > 1)
  455.     {
  456.         switch(Mode)
  457.         {
  458.                 /* Erase from left margin to current cursor position (inclusive). */
  459.  
  460.             case 1:    ScrollLines[CursorY] . Left = CursorX + 1;
  461.                 break;
  462.  
  463.                 /* Erase entire line. */
  464.  
  465.             case 2:    ScrollLines[CursorY] . Left    = 255;
  466.                 ScrollLines[CursorY] . Right    = 0;
  467.  
  468.                 break;
  469.  
  470.                 /* Erase from current cursor position towards end of line. */
  471.  
  472.             default:if(CursorX)
  473.                     ScrollLines[CursorY] . Right = CursorX;
  474.                 else
  475.                 {
  476.                     ScrollLines[CursorY] . Left    = 255;
  477.                     ScrollLines[CursorY] . Right    = 0;
  478.                 }
  479.  
  480.                 break;
  481.         }
  482.  
  483.             /* Adapt possible changes in the lines for first and last line. */
  484.  
  485.         while(ScrollLineFirst < RasterHeight)
  486.         {
  487.             if(ScrollLines[ScrollLineFirst] . Left > ScrollLines[ScrollLineFirst] . Right)
  488.                 ScrollLineFirst++;
  489.             else
  490.                 break;
  491.         }
  492.  
  493.         while(ScrollLineLast > 0)
  494.         {
  495.             if(ScrollLines[ScrollLineLast] . Left > ScrollLines[ScrollLineLast] . Right)
  496.                 ScrollLineLast--;
  497.             else
  498.                 break;
  499.         }
  500.     }
  501. }
  502.  
  503.     /* ScrollLineEraseCharacters(WORD Chars):
  504.      *
  505.      *    Erase a number of characters in the current cursor line.
  506.      */
  507.  
  508. VOID __regargs
  509. ScrollLineEraseCharacters(WORD Chars)
  510. {
  511.     if(RPort -> BitMap -> Depth > 1)
  512.     {
  513.             /* Any characters to erase? */
  514.  
  515.         if(ScrollLines[CursorY] . Right)
  516.             ScrollLines[CursorY] . Right -= Chars;
  517.     }
  518. }
  519.  
  520.     /* ScrollLineShiftChar(WORD Size):
  521.      *
  522.      *    Shift the characters following the current cursor position
  523.      *    Size characters to the right.
  524.      */
  525.  
  526. VOID __regargs
  527. ScrollLineShiftChar(WORD Size)
  528. {
  529.     if(RPort -> BitMap -> Depth > 1)
  530.     {
  531.             /* Any characters to scroll? */
  532.  
  533.         if(ScrollLines[CursorY] . Right)
  534.             ScrollLines[CursorY] . Right += Size;
  535.     }
  536. }
  537.  
  538.     /* ScrollLinePutString(WORD Length):
  539.      *
  540.      *    Update the line info according to the length of a string
  541.      *    to be printed.
  542.      */
  543.  
  544. VOID __regargs
  545. ScrollLinePutString(WORD Length)
  546. {
  547.     if(RPort -> BitMap -> Depth > 1)
  548.     {
  549.         BYTE Shift;
  550.  
  551.             /* Which scale is the font we are currently using? */
  552.  
  553.         if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  554.         {
  555.                 /* Valid length? */
  556.  
  557.             if(CursorX + Length >= RasterWidth >> 1)
  558.                 Length = (RasterWidth >> 1) - CursorX;
  559.  
  560.                 /* Double width (16 pixels wide). */
  561.  
  562.             Shift = 4;
  563.         }
  564.         else
  565.         {
  566.             if(Config . FontScale == SCALE_HALF)
  567.             {
  568.                     /* Valid length? */
  569.  
  570.                 if(CursorX + Length >= RasterWidth << 1)
  571.                     Length = (RasterWidth << 1) - CursorX;
  572.  
  573.                     /* Half width (4 pixels wide). */
  574.  
  575.                 Shift = 2;
  576.             }
  577.             else
  578.             {
  579.                     /* Valid length? */
  580.  
  581.                 if(CursorX + Length >= RasterWidth)
  582.                     Length = RasterWidth - CursorX;
  583.  
  584.                     /* Normal width (8 pixels wide). */
  585.  
  586.                 Shift = 3;
  587.             }
  588.         }
  589.  
  590.             /* Sensible value? */
  591.  
  592.         if(Length > 0)
  593.         {
  594.             struct ScrollLineInfo *Alias = &ScrollLines[CursorY];
  595.  
  596.                 /* Update line colour mask. */
  597.  
  598.             Alias -> ColourMask |= (RPort -> FgPen|RPort -> BgPen);
  599.  
  600.                 /* Update font scale. */
  601.  
  602.             Alias -> Shift = Shift;
  603.  
  604.                 /* Set write mask (will affect Text() since it is called
  605.                  * after this routine has finished.
  606.                  */
  607.  
  608.             if(!(Config . DisableBlinking & TERMINAL_FASTER))
  609.                 SetWrMsk(RPort,Alias -> ColourMask);
  610.  
  611.                 /* Update right margin. */
  612.  
  613.             if(CursorX < Alias -> Left)
  614.                 Alias -> Left = CursorX;
  615.  
  616.                 /* Update left margin. */
  617.  
  618.             if(CursorX + Length > Alias -> Right)
  619.                 Alias -> Right = CursorX + Length;
  620.  
  621.                 /* Update topmost line. */
  622.  
  623.             if(CursorY < ScrollLineFirst)
  624.                 ScrollLineFirst = CursorY;
  625.  
  626.                 /* Update bottommost line. */
  627.  
  628.             if(CursorY > ScrollLineLast)
  629.                 ScrollLineLast = CursorY;
  630.         }
  631.     }
  632. }
  633.